version: '3.5'

services:

  #
  # Kuma Control Plane in "universal" mode with "in-memory" configuration store.
  #
  kuma-control-plane:
    # image name must be provided via environment variable KUMA_CP_DOCKER_IMAGE
    image: ${KUMA_CP_DOCKER_IMAGE:-kuma/kuma-cp:latest}
    volumes:
    - ./certs/server:/certs/server
    - ./certs/client/cert.pem:/certs/client/cert.pem
    command:
    - run
    - --log-level=info
    environment:
    # DNS name of the Kuma xDS server
    - KUMA_GENERAL_TLS_CERT_FILE=/certs/server/cert.pem
    - KUMA_GENERAL_TLS_KEY_FILE=/certs/server/key.pem
    - KUMA_API_SERVER_AUTHN_TYPE=adminClientCerts
    - KUMA_API_SERVER_AUTH_CLIENT_CERTS_DIR=/certs/client
    expose:
    - "5678"
    - "5680"
    - "5681"
    - "5682"
    ports:
    - "5678:5678"
    - "5680:5680"
    - "5681:5681"
    - "5682:5682"
    networks:
      kuma-example:
        aliases:
        - kuma-control-plane
    restart: on-failure

  #
  # Installation script for Kuma example.
  #
  # Uses `kumactl` to create Dataplane resources, generate dataplane tokens, etc.
  #
  kuma-example-installer:
    # image name must be provided via environment variable KUMACTL_DOCKER_IMAGE
    image: ${KUMACTL_DOCKER_IMAGE:-kuma/kumactl:latest}
    volumes:
    - ./kuma-example-installer.sh:/kuma-example/kuma-example-installer.sh
    - token-example-app:/kuma-example-app:rw
    - token-example-client:/kuma-example-client:rw
    - token-example-web:/kuma-example-web:rw
    - token-example-backend-v1:/kuma-example-backend-v1:rw
    - token-example-backend-v2:/kuma-example-backend-v2:rw
    - ./certs/server/cert.pem:/certs/server/cert.pem
    - ./certs/client:/certs/client
    user: root # needed to write the tokens, named volumes are mounted with root permissions
    command:
      - /kuma-example/kuma-example-installer.sh
    networks:
      kuma-example: {}
    depends_on:
      - kuma-control-plane
    restart: on-failure

  #
  # Container with `kumactl` to edit Kuma resources as part of e2e workflow.
  #
  kumactl:
    # image name must be provided via environment variable KUMACTL_DOCKER_IMAGE
    image: ${KUMACTL_DOCKER_IMAGE:-kuma/kumactl:latest}
    volumes:
    - ./policies:/kuma-example/policies
    command:
    - sh
    - -c
    - kumactl config control-planes add --name universal --address http://kuma-control-plane:5681 --overwrite && sleep 31536000
    networks:
      kuma-example: {}
    depends_on:
      - kuma-control-plane
    restart: on-failure

  #
  # Auxiliary service (container) for sharing Linux network namespace
  # between Example Application and Kuma Sidecar.
  #
  kuma-example-app-namespace:
    image: busybox:1.31.0
    command: ["sleep", "infinity"]
    # The following `expose` configuration was originally a part of `kuma-example-app` service.
    # However, `expose` settings are incompatible with `network_mode: service:...`
    # and had to be moved here.
    expose:
    - "8000"
    # The following `ports` configuration was originally a part of `kuma-example-app` service.
    # However, `ports` settings are incompatible with `network_mode: service:...`
    # and had to be moved here.
    ports:
    - "8000:80"
    networks:
      kuma-example:
        aliases:
        - kuma-example-app
    depends_on:
    - kuma-control-plane
    restart: on-failure

  #
  # Example application deployed into Kuma mesh.
  #
  # Notice that we're using Kong (API Gateway) as an example application
  # since it's a perfect example of a (micro-)service that is both
  # source and destination for network requests.
  #
  kuma-example-app:
    image: nginx:stable
    network_mode: service:kuma-example-app-namespace
    depends_on:
    - kuma-example-app-namespace
    restart: on-failure

  #
  # Kuma sidecar for the example application.
  #
  kuma-example-app-sidecar:
    # image name must be provided via environment variable KUMA_DP_DOCKER_IMAGE
    image: ${KUMA_DP_DOCKER_IMAGE:-kuma/kuma-dp:latest}
    command:
    - run
    - --log-level=info
    environment:
    - KUMA_CONTROL_PLANE_URL=https://kuma-control-plane:5678
    - KUMA_DATAPLANE_MESH=default
    - KUMA_DATAPLANE_NAME=kuma-example-app
    - KUMA_DATAPLANE_RUNTIME_TOKEN_PATH=/token-example-app/token
    # the following setting instructs Docker Compose to add `kuma-example-app-sidecar` container
    # to the network namespace of `kuma-example-app-namespace` container
    network_mode: service:kuma-example-app-namespace
    depends_on:
    - kuma-example-app-namespace
    restart: on-failure
    volumes:
    - token-example-app:/token-example-app

  #
  # Auxiliary service (container) for sharing Linux network namespace
  # between Example Client and Kuma Sidecar.
  #
  kuma-example-client-namespace:
    image: busybox:1.31.0
    command: ["sleep", "infinity"]
    # The following `expose` configuration was originally a part of `kuma-example-client` service.
    # However, `expose` settings are incompatible with `network_mode: service:...`
    # and had to be moved here.
    expose:
    - "3000"
    # The following `ports` configuration was originally a part of `kuma-example-client` service.
    # However, `ports` settings are incompatible with `network_mode: service:...`
    # and had to be moved here.
    ports:
    - "3000:3000"
    networks:
      kuma-example:
        aliases:
        - kuma-example-client
    depends_on:
    - kuma-control-plane
    restart: on-failure

  #
  # Example client deployed into Kuma mesh.
  #
  kuma-example-client:
    image: docker.io/kumahq/curl
    command:
    - nc
    - -lk
    - -s
    - 127.0.0.1
    - -p
    - "3000"
    - -e
    - curl
    - --silent
    - --show-error
    - --include
    - --fail
    - http://kuma-example-app:8000/
    # the following setting instructs Docker Compose to add `kuma-example-client` container
    # to the network namespace of `kuma-example-client-namespace` container
    network_mode: service:kuma-example-client-namespace
    depends_on:
    - kuma-example-client-namespace
    restart: on-failure

  #
  # Kuma sidecar for the example client.
  #
  kuma-example-client-sidecar:
    # image name must be provided via environment variable KUMA_DP_DOCKER_IMAGE
    image: ${KUMA_DP_DOCKER_IMAGE:-kuma/kuma-dp:latest}
    command:
    - run
    - --log-level=info
    environment:
    - KUMA_CONTROL_PLANE_URL=https://kuma-control-plane:5678
    - KUMA_DATAPLANE_MESH=default
    - KUMA_DATAPLANE_NAME=kuma-example-client
    - KUMA_DATAPLANE_RUNTIME_TOKEN_PATH=/token-example-client/token
    # the following setting instructs Docker Compose to add `kuma-example-app-sidecar` container
    # to the network namespace of `kuma-example-app-namespace` container
    network_mode: service:kuma-example-client-namespace
    depends_on:
    - kuma-example-client-namespace
    restart: on-failure
    volumes:
      - token-example-client:/token-example-client

  #                            -> backend-v1  :  version: v1, env=prod
  #                          /
  # Example of routing web -
  #                          \
  #                            -> backend-v2  :  version: v2, env=intg

  #
  # Auxiliary service (container) for sharing Linux network namespace
  # between Example Web and Kuma Sidecar.
  #
  kuma-example-web-namespace:
    image: busybox:1.31.0
    command: ["sleep", "infinity"]
    expose:
    - "6060"
    # The following `ports` configuration was originally a part of `kuma-example-web` service.
    # However, `ports` settings are incompatible with `network_mode: service:...`
    # and had to be moved here.
    ports:
    - "6060:6060"
    networks:
      kuma-example:
        aliases:
        - kuma-example-web
    depends_on:
    - kuma-control-plane
    restart: on-failure

  #
  # Example Web deployed into Kuma mesh.
  #
  kuma-example-web:
    image: docker.io/kumahq/curl
    command:
    - nc
    - -lk
    - -s
    - 127.0.0.1
    - -p
    - "6060"
    - -e
    - curl
    - --silent
    - --show-error
    - --include
    - --fail
    - http://localhost:5000/version
    # the following setting instructs Docker Compose to add `kuma-example-web` container
    # to the network namespace of `kuma-example-web-namespace` container
    network_mode: service:kuma-example-web-namespace
    depends_on:
    - kuma-example-web-namespace
    restart: on-failure

  #
  # Kuma sidecar for the Example Web.
  #
  kuma-example-web-sidecar:
    # image name must be provided via environment variable KUMA_DP_DOCKER_IMAGE
    image: ${KUMA_DP_DOCKER_IMAGE:-kuma/kuma-dp:latest}
    command:
    - run
    - --log-level=info
    volumes:
    - token-example-web:/var/kuma.io/kuma-dp/kuma-example-web
    environment:
    - KUMA_CONTROL_PLANE_URL=https://kuma-control-plane:5678
    - KUMA_DATAPLANE_MESH=default
    - KUMA_DATAPLANE_NAME=kuma-example-web
    - KUMA_DATAPLANE_RUNTIME_TOKEN_PATH=/var/kuma.io/kuma-dp/kuma-example-web/token
    # the following setting instructs Docker Compose to add `kuma-example-web-sidecar` container
    # to the network namespace of `kuma-example-web-namespace` container
    network_mode: service:kuma-example-web
    depends_on:
    - kuma-example-web
    restart: on-failure

  #
  # Auxiliary service (container) for sharing Linux network namespace
  # between Example Backend v1 and Kuma Sidecar.
  #
  kuma-example-backend-v1-namespace:
    image: busybox:1.31.0
    command: ["sleep", "infinity"]
    expose:
    - "7070"
    # The following `ports` configuration was originally a part of `kuma-example-backend-v1` service.
    # However, `ports` settings are incompatible with `network_mode: service:...`
    # and had to be moved here.
    ports:
    - "17070:7070"
    networks:
      kuma-example:
        aliases:
        - kuma-example-backend-v1
    depends_on:
    - kuma-control-plane
    restart: on-failure

  #
  # Example Backend v1 deployed into Kuma mesh.
  #
  # Notice that we're using Envoy as a simple HTTP server with predefined responses.
  #
  kuma-example-backend-v1:
    image: envoyproxy/envoy-alpine:v1.16.1
    command:
    - sh
    - -c
    - echo '{"version":"v1"}' >/tmp/response.json ; envoy -c /etc/envoy/backend.yaml
    volumes:
    - ./backend.yaml:/etc/envoy/backend.yaml
    # the following setting instructs Docker Compose to add `kuma-example-backend-v1` container
    # to the network namespace of `kuma-example-backend-v1-namespace` container
    network_mode: service:kuma-example-backend-v1-namespace
    depends_on:
    - kuma-example-backend-v1-namespace
    restart: on-failure

  #
  # Kuma sidecar for the Example Backend v1.
  #
  kuma-example-backend-v1-sidecar:
    # image name must be provided via environment variable KUMA_DP_DOCKER_IMAGE
    image: ${KUMA_DP_DOCKER_IMAGE:-kuma/kuma-dp:latest}
    command:
    - run
    - --log-level=info
    volumes:
    - token-example-backend-v1:/var/kuma.io/kuma-dp/kuma-example-backend-v1
    environment:
    - KUMA_CONTROL_PLANE_URL=https://kuma-control-plane:5678
    - KUMA_DATAPLANE_MESH=default
    - KUMA_DATAPLANE_NAME=kuma-example-backend-v1
    - KUMA_DATAPLANE_RUNTIME_TOKEN_PATH=/var/kuma.io/kuma-dp/kuma-example-backend-v1/token
    # the following setting instructs Docker Compose to add `kuma-example-backend-v1-sidecar` container
    # to the network namespace of `kuma-example-backend-v1-namespace` container
    network_mode: service:kuma-example-backend-v1
    depends_on:
    - kuma-example-backend-v1
    restart: on-failure

  #
  # Auxiliary service (container) for sharing Linux network namespace
  # between Example Backend v2 and Kuma Sidecar.
  #
  kuma-example-backend-v2-namespace:
    image: busybox:1.31.0
    command: ["sleep", "infinity"]
    expose:
    - "7070"
    # The following `ports` configuration was originally a part of `kuma-example-backend-v2` service.
    # However, `ports` settings are incompatible with `network_mode: service:...`
    # and had to be moved here.
    ports:
    - "27070:7070"
    networks:
      kuma-example:
        aliases:
        - kuma-example-backend-v2
    depends_on:
    - kuma-control-plane
    restart: on-failure

  #
  # Example Backend v2 deployed into Kuma mesh.
  #
  # Notice that we're using Envoy as a simple HTTP server with predefined responses.
  #
  kuma-example-backend-v2:
    image: envoyproxy/envoy-alpine:v1.16.1
    command:
    - sh
    - -c
    - echo '{"version":"v2"}' >/tmp/response.json ; envoy -c /etc/envoy/backend.yaml
    volumes:
    - ./backend.yaml:/etc/envoy/backend.yaml
    # the following setting instructs Docker Compose to add `kuma-example-backend-v2` container
    # to the network namespace of `kuma-example-backend-v2-namespace` container
    network_mode: service:kuma-example-backend-v2-namespace
    depends_on:
    - kuma-example-backend-v2-namespace
    restart: on-failure

  #
  # Kuma sidecar for the Example Backend v2.
  #
  kuma-example-backend-v2-sidecar:
    # image name must be provided via environment variable KUMA_DP_DOCKER_IMAGE
    image: ${KUMA_DP_DOCKER_IMAGE:-kuma/kuma-dp:latest}
    command:
    - run
    - --log-level=info
    volumes:
    - token-example-backend-v2:/var/kuma.io/kuma-dp/kuma-example-backend-v2
    environment:
    - KUMA_CONTROL_PLANE_URL=https://kuma-control-plane:5678
    - KUMA_DATAPLANE_MESH=default
    - KUMA_DATAPLANE_NAME=kuma-example-backend-v2
    - KUMA_DATAPLANE_RUNTIME_TOKEN_PATH=/var/kuma.io/kuma-dp/kuma-example-backend-v2/token
    # the following setting instructs Docker Compose to add `kuma-example-backend-v2-sidecar` container
    # to the network namespace of `kuma-example-backend-v2-namespace` container
    network_mode: service:kuma-example-backend-v2
    depends_on:
    - kuma-example-backend-v2
    restart: on-failure

networks:
  kuma-example: {}

volumes:
  token-example-app:
  token-example-client:
  token-example-web:
  token-example-backend-v1:
  token-example-backend-v2:
